﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using WcfServer.Classes.Utility;
using WcfServer.Classes.Client;

namespace P2P_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("1: Export key\n2: Begin Listening for connection\n3: Initiate connection\nElse: Exit");
            Console.WriteLine("Select an option: ");

            int option;
            option = int.Parse(Console.ReadLine());
            if(option == 1 || option == 2 || option == 3)
            {
				switch (option)
	            {
                    case 1:

                        Console.WriteLine("Enter UserName: ");
                        String UserName = Console.ReadLine();
                        Console.WriteLine("Enter True for private key, False for public key: ");
                        bool Private = bool.Parse(Console.ReadLine());
                        Console.WriteLine("Enter FileName: ");
                        String FileName = Console.ReadLine();
                        FileStream fs = new FileStream(FileName,FileMode.OpenOrCreate,FileAccess.ReadWrite);
                        StreamWriter sw = new StreamWriter(fs);
                        sw.WriteLine(KeyHandler.getKey_XML(UserName,Private));
                        sw.Close();
                        fs.Close();

                        break;
                    case 2:
                        Console.WriteLine("Enter required information sequentially (src_ip, dst_ip, port, src_name, dst_name) in each line");
                        String src_ip=Console.ReadLine(), dst_ip=Console.ReadLine();
                        int port=int.Parse(Console.ReadLine());
                        String src_name=Console.ReadLine(), dst_name=Console.ReadLine();
                        listen(src_ip,dst_ip,port,null,src_name,dst_name);
                        Console.WriteLine("Listening thread started...");
                        break;

                    case 3:
                        Console.WriteLine("Enter Public XML FileName: ");
                        FileName = Console.ReadLine();
                        fs = new FileStream(FileName,FileMode.Open,FileAccess.Read);
                        StreamReader sr = new StreamReader(fs);
                        String xml = sr.ReadToEnd();
                        sr.Close();
                        fs.Close();
                        Console.WriteLine("Enter required information sequentially (src_ip, dst_ip, port, src_name, dst_name) in each line");
                        init(Console.ReadLine(), Console.ReadLine(), int.Parse(Console.ReadLine()), xml, Console.ReadLine(), Console.ReadLine());

                        break;
	            	default:
                        break;
	            }
                
            }


        }

        static void listen(String src_ip, String dst_ip, int Port, String XMLPub, String src_name, String dst_name)
        {
            var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipe = new IPEndPoint(IPAddress.Any, Port);
            listener.Bind(ipe);
            listener.Listen(4);
            while (true)
            {
                var soc = listener.Accept();
                //TODO: what happens to the last one created? does the communicate(soc) continues if the new object replaces the old one?!!!
                DirectConnectionHandler dch = new DirectConnectionHandler(soc, src_name, dst_name, src_ip, dst_ip, XMLPub);
                dch.ListenConnection();
                //TODO:CHECK if allowed to go to communicate.
                dch.IsConnectionOpen = true;
                dch.Communicate();
            }
        }

        static void init(String src_ip,String dst_ip, int Port, String XMLPub, String src_name, String dst_name)
        {
            //TODO: It should be threaded and called for different connections (specially needed when UI comes up).            
            Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soc.Connect(IPAddress.Parse(dst_ip), Port);

            DirectConnectionHandler dch = new DirectConnectionHandler(soc, src_name, dst_name, src_ip, dst_ip, XMLPub);
            dch.InitiateConnection();
            //TODO:CHECK if allowed to go to communicate.
            dch.IsConnectionOpen = true;

            dch.Communicate();
        }
    }
}